package com.ruoyi.purchase.service.impl;

import java.util.*;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.purchase.domain.*;
import com.ruoyi.purchase.mapper.BoxCodesMapper;
import com.ruoyi.purchase.mapper.DeliveryMapper;
import com.ruoyi.purchase.mapper.PurchaseOrdersMapper;
import com.ruoyi.purchase.service.IBoxCodesService;
import com.ruoyi.purchase.service.IDeliveryService;
import com.ruoyi.purchase.service.IInspectionPlanService;
import com.ruoyi.purchase.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.purchase.mapper.MaterialReceiveMapper;
import com.ruoyi.purchase.service.IMaterialReceiveService;

/**
 * 收料通知单Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-10-29
 */
@Service
public class MaterialReceiveServiceImpl implements IMaterialReceiveService 
{
    @Autowired
    private MaterialReceiveMapper materialReceiveMapper;

    @Autowired
    private DeliveryMapper deliveryMapper;

    @Autowired
    private IDeliveryService deliveryService;

    @Autowired
    private IBoxCodesService boxCodesService;

    @Autowired
    private BoxCodesMapper boxCodesMapper;

    @Autowired
    private PurchaseOrdersMapper purchaseOrdersMapper;

    @Autowired
    private IInspectionPlanService inspectionPlanService;

    @Override
    public AjaxResult scanCode(String code, boolean sameBatch) {

        try {
            MaterialReceiveVO  result = new MaterialReceiveVO();
            // 判断是送货单号还是箱码
            if (code.startsWith("DN")) {
                // 按送货单号查询 根据送货id得到了送货单主表VO
                DeliveryVO deliveryVO1 = deliveryMapper.selectDeliveryVOByDeliveryId(code);

                // 根据送货单主表VO查id
                DeliveryVO deliveryVO = deliveryService.selectDeliveryVOById(deliveryVO1.getId());
                if (deliveryVO == null) {
                    return AjaxResult.error("未找到对应的送货单");
                }

                result.setPoId(deliveryVO.getPoId());
                result.setDeliveryId(deliveryVO.getDeliveryId());

                // 将 DeliveryItemVO 转换为 MaterialReceiveItemVO
                if (deliveryVO.getDeliveryItems() != null) {
                    List<MaterialReceiveItemVO> receiveItems = new ArrayList<>();
                    for (DeliveryItemVO deliveryItem : deliveryVO.getDeliveryItems()) {
                        MaterialReceiveItemVO receiveItem = new MaterialReceiveItemVO();
                        receiveItem.setPoId(deliveryVO.getPoId());
                        receiveItem.setItemId(deliveryItem.getItemId());
                        receiveItem.setPoNum(deliveryItem.getPoNum());
                        receiveItem.setPayoffNum(deliveryItem.getCodeNum());
                        receiveItem.setItemName(deliveryItem.getItemName());
                        receiveItem.setCurrentDeliveryQuantity(deliveryItem.getCurrentDeliveryQuantity());
                        receiveItem.setCurrentReceiveQuantity(deliveryItem.getCurrentDeliveryQuantity()); // 本次收货数量 = 本次送货数量
                        receiveItem.setBoxCount(deliveryItem.getBoxCount());
                        receiveItems.add(receiveItem);
                    }
                    result.setReceiveItems(receiveItems);
                }
                result.setBoxCodes(deliveryVO.getBoxCodes());

            } else {
                // 按箱码查询
                BoxCodesVO boxCode = boxCodesMapper.selectBoxCodesByboxId(code);
                if (boxCode == null) {
                    return AjaxResult.error("未找到对应的箱码");
                }

                if (sameBatch) {
                    // 带入同批次，查询该送货单下的所有箱码 根据箱码找发货单id和id
                    DeliveryDetail deliveryVO1 = deliveryMapper.selectdeliveryIdandIDByboxId(boxCode.getBoxId());
                    //根据发货单id查发货单主表先
                    DeliveryVO deliveryVO2 = deliveryMapper.selectDeliveryVOByDeliveryId(deliveryVO1.getDeliveryId());
                    DeliveryVO deliveryVO = deliveryService.selectDeliveryVOById(deliveryVO2.getId());

                    if (deliveryVO != null) {
                        result.setPoId(deliveryVO.getPoId());
                        result.setDeliveryId(deliveryVO.getDeliveryId());
                        // 将 DeliveryItemVO 转换为 MaterialReceiveItemVO
                        if (deliveryVO.getDeliveryItems() != null) {
                            List<MaterialReceiveItemVO> receiveItems = new ArrayList<>();
                            for (DeliveryItemVO deliveryItem : deliveryVO.getDeliveryItems()) {
                                MaterialReceiveItemVO receiveItem = new MaterialReceiveItemVO();
                                receiveItem.setPoId(deliveryVO.getPoId());
                                receiveItem.setItemId(deliveryItem.getItemId());
                                receiveItem.setItemName(deliveryItem.getItemName());
                                receiveItem.setPoNum(deliveryItem.getPoNum());
                                receiveItem.setPayoffNum(deliveryItem.getCodeNum());
                                receiveItem.setCurrentDeliveryQuantity(deliveryItem.getCurrentDeliveryQuantity());
                                receiveItem.setCurrentReceiveQuantity(deliveryItem.getCurrentDeliveryQuantity()); // 本次收货数量 = 本次送货数量
                                receiveItem.setBoxCount(deliveryItem.getBoxCount());
                                receiveItems.add(receiveItem);
                            }
                            result.setReceiveItems(receiveItems);
                        }

                        result.setBoxCodes(deliveryVO.getBoxCodes());
                    }
                } else {
                    // 只查询当前箱码
                    DeliveryVO deliveryVO = deliveryMapper.selectDeliveryVOByDeliveryId(code);
                    result.setPoId(boxCode.getPoId());
                    result.setDeliveryId(boxCode.getPoId()); // 这里需要根据箱码获取送货单号
                    result.setBoxCodes(Arrays.asList(boxCode));

                    PurchaseOrdersDetails purchaseOrdersDetails= purchaseOrdersMapper.selectDetailByPoIdAndItemId(boxCode.getPoId(),(boxCode.getItemId()));
                    // 构建收料清单
                    MaterialReceiveItemVO item = new MaterialReceiveItemVO();
                    item.setPoId(boxCode.getPoId());
                    item.setItemId(boxCode.getItemId());
                    item.setItemName(boxCode.getItemName());
                    item.setPoNum(purchaseOrdersDetails.getPoNum());
                    item.setPayoffNum(purchaseOrdersDetails.getCodeNum());
                    item.setCurrentDeliveryQuantity(boxCode.getBoxNum());
                    item.setCurrentReceiveQuantity(boxCode.getBoxNum());
                    item.setBoxCount(1L);
                    result.setReceiveItems(Arrays.asList(item));
                }
            }

            // 设置默认收料人
            result.setReceiver("仓储李经理");
            result.setReceiveDate(new Date());

            return AjaxResult.success("扫码成功", result);
        } catch (Exception e) {
            return AjaxResult.error("扫码失败: " + e.getMessage());
        }


    }

    @Override
    public AjaxResult updateRejectStatus(Long detailId, Long isRejected) {
        return null;
    }

    /**
     * 生成收料通知单的
     *
     * @param materialReceive 收料通知单
     * @return 收料通知单
     */
    @Override
    public String generateReceiveId() {
        String dateStr = DateUtils.parseDateToStr("yyMMdd",new Date());
        String prefix = "MRC" + dateStr;
        String maxReceiveId = materialReceiveMapper.selectMaxReceiveId(prefix);
        if (maxReceiveId == null) {
            return prefix + "001";
        } else {
            String sequence = maxReceiveId.substring(9);
            int nextSeq = Integer.parseInt(sequence) + 1;
            return prefix + String.format("%03d", nextSeq);
        }
    }

    /**
     * 新增收料通知单到收料主表和详情表
     *
     * @param id 收料通知单主键
     * @return 收料通知单
     */
    @Override
    @Transactional
    public AjaxResult addMaterialReceiveWithDetails(MaterialReceiveVO materialReceiveVO) {
        try {
            System.out.println("新增收料通知"+materialReceiveVO);
            // 1. 生成收料通知单号
            String receiveId = this.generateReceiveId();
            materialReceiveVO.setReceiveId(receiveId);

            // 2. 保存收料通知单主表
            MaterialReceive materialReceive = new MaterialReceive();
            BeanUtils.copyProperties(materialReceiveVO, materialReceive);
            materialReceive.setCreatedPerson(SecurityUtils.getUsername());
            materialReceiveMapper.insertMaterialReceive(materialReceive);

            // 3. 保存收料通知单明细
            if (materialReceiveVO.getBoxCodes() != null && !materialReceiveVO.getBoxCodes().isEmpty()) {
                List<MaterialReceiveDetail> detailList = new ArrayList<>();
                for (BoxCodesVO boxCode : materialReceiveVO.getBoxCodes()) {
                    MaterialReceiveDetail detail = new MaterialReceiveDetail();
                    detail.setReceiveId(receiveId);
                    detail.setBoxId(boxCode.getBoxId());
                    detail.setRecevingStatus(0L); // 默认未拒收
                    detail.setCreatedAt(new Date());
                    detail.setUpdatedAt(new Date());
                    detailList.add(detail);
                }
                materialReceiveMapper.batchMaterialReceiveDetail(detailList);

            }

            // 暂停当前线程2秒
            Thread.sleep(5000);

            // 4. 自动生成检验计划
            AjaxResult planResult = inspectionPlanService.createInspectionPlansFromReceive(receiveId);

            if (!planResult.isSuccess()) {
                // 如果检验计划创建失败，记录日志但不中断流程
                AjaxResult.success("自动生成检验计划失败");
            } else {
                AjaxResult.success("自动生成检验计划失败");
            }


            return AjaxResult.success("收料通知单创建成功");
        } catch (Exception e) {
            throw new RuntimeException("收料通知单创建失败: " + e.getMessage());
        }
    }

    @Override
    public List<MaterialReceiveVO> selectMaterialReceiveVOList(MaterialReceive materialReceive) {
        List<MaterialReceiveVO> receiveList = materialReceiveMapper.selectMaterialReceiveVOList(materialReceive);
        // 为每个收料通知单加载箱码信息
        for (MaterialReceiveVO receiveVO : receiveList) {
            List<BoxCodesVO> boxCodes = materialReceiveMapper.selectBoxCodesByReceiveId(receiveVO.getReceiveId());
            receiveVO.setBoxCodes(boxCodes);

            // 计算收料清单汇总
            receiveVO.setReceiveItems(calculateReceiveItems(boxCodes));
        }
        return receiveList;


    }

    /**
     * 根据id搜索收料通知
     *
     * @param id 收料通知单主键
     * @return 收料通知单
     */


    @Override
    public MaterialReceiveVO selectMaterialReceiveVOById(Long id) {
        MaterialReceiveVO receiveVO = materialReceiveMapper.selectMaterialReceiveVOById(id);
        if (receiveVO != null) {
            List<BoxCodesVO> boxCodes = materialReceiveMapper.selectBoxCodesByReceiveId(receiveVO.getReceiveId());
            receiveVO.setBoxCodes(boxCodes);
            receiveVO.setReceiveItems(calculateReceiveItems(boxCodes));
            System.out.println("详情"+receiveVO);
        }
        return receiveVO;
    }



    /**
     * 查询收料通知单
     * 
     * @param id 收料通知单主键
     * @return 收料通知单
     */
    @Override
    public MaterialReceive selectMaterialReceiveById(Long id)
    {
        return materialReceiveMapper.selectMaterialReceiveById(id);
    }

    /**
     * 查询收料通知单列表
     * 
     * @param materialReceive 收料通知单
     * @return 收料通知单
     */
    @Override
    public List<MaterialReceive> selectMaterialReceiveList(MaterialReceive materialReceive)
    {
        return materialReceiveMapper.selectMaterialReceiveList(materialReceive);
    }

    /**
     * 新增收料通知单
     * 
     * @param materialReceive 收料通知单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertMaterialReceive(MaterialReceive materialReceive)
    {
        int rows = materialReceiveMapper.insertMaterialReceive(materialReceive);
        insertMaterialReceiveDetail(materialReceive);
        return rows;
    }

    /**
     * 修改收料通知单
     * 
     * @param materialReceive 收料通知单
     * @return 结果
     */
    @Transactional
    @Override
    public int updateMaterialReceive(MaterialReceive materialReceive)
    {
        materialReceiveMapper.deleteMaterialReceiveDetailByReceiveId(materialReceive.getId());
        insertMaterialReceiveDetail(materialReceive);
        return materialReceiveMapper.updateMaterialReceive(materialReceive);
    }

    /**
     * 批量删除收料通知单
     * 
     * @param ids 需要删除的收料通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMaterialReceiveByIds(Long[] ids)
    {
        materialReceiveMapper.deleteMaterialReceiveDetailByReceiveIds(ids);
        return materialReceiveMapper.deleteMaterialReceiveByIds(ids);
    }

    /**
     * 删除收料通知单信息
     * 
     * @param id 收料通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMaterialReceiveById(Long id)
    {
        materialReceiveMapper.deleteMaterialReceiveDetailByReceiveId(id);
        return materialReceiveMapper.deleteMaterialReceiveById(id);
    }

    /**
     * 新增${subTable.functionName}信息
     * 
     * @param materialReceive 收料通知单对象
     */
    public void insertMaterialReceiveDetail(MaterialReceive materialReceive)
    {
        List<MaterialReceiveDetail> materialReceiveDetailList = materialReceive.getMaterialReceiveDetailList();
        Long id = materialReceive.getId();
        if (StringUtils.isNotNull(materialReceiveDetailList))
        {
            List<MaterialReceiveDetail> list = new ArrayList<MaterialReceiveDetail>();
            for (MaterialReceiveDetail materialReceiveDetail : materialReceiveDetailList)
            {
                materialReceiveDetail.setReceiveId(String.valueOf(id));
                list.add(materialReceiveDetail);
            }
            if (list.size() > 0)
            {
                materialReceiveMapper.batchMaterialReceiveDetail(list);
            }
        }
    }

    private List<MaterialReceiveItemVO> calculateReceiveItems(List<BoxCodesVO> boxCodes) {
        Map<String, MaterialReceiveItemVO> itemMap = new HashMap<>();
        for (BoxCodesVO boxCode : boxCodes) {
            String itemId = boxCode.getItemId();
            PurchaseOrdersDetails purchaseOrdersDetails= purchaseOrdersMapper.selectDetailByPoIdAndItemId(boxCode.getPoId(),itemId);

            MaterialReceiveItemVO itemVO = itemMap.get(itemId);

            if (itemVO == null) {
                itemVO = new MaterialReceiveItemVO();
                itemVO.setPoId(purchaseOrdersDetails.getPoId());
                itemVO.setPoNum(purchaseOrdersDetails.getPoNum());
                itemVO.setPayoffNum(purchaseOrdersDetails.getCodeNum());
                itemVO.setItemId(itemId);
                itemVO.setBatch(boxCode.getBatch());
                itemVO.setItemName(boxCode.getItemName());
                itemVO.setCurrentDeliveryQuantity(0L);
                itemVO.setCurrentReceiveQuantity(0L);
                itemVO.setBoxCount(0L);
                itemMap.put(itemId, itemVO);
            }

            // 累加数量和箱数
            itemVO.setCurrentDeliveryQuantity(itemVO.getCurrentDeliveryQuantity() + boxCode.getBoxNum());
            itemVO.setCurrentReceiveQuantity(itemVO.getCurrentReceiveQuantity() + boxCode.getBoxNum());
            itemVO.setBoxCount(itemVO.getBoxCount() + 1);
        }

        return new ArrayList<>(itemMap.values());
    }
}
